/**
 * 
 */
package org.ejc.struts.registration;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.DispatchAction;
import org.ejc.api.email.EmailAPIUtil;
import org.ejc.api.registration.RegistrationAPIUtil;
import org.ejc.persist.model.AccomodationType;
import org.ejc.persist.model.Address;
import org.ejc.persist.model.ConventionRegistrant;
import org.ejc.persist.model.CountryCode;
import org.ejc.persist.model.Registrant;
import org.ejc.persist.model.RegistrantType;
import org.ejc.session.EJCSession;
import org.ejc.struts.address.AddressForm;
import org.ejc.tech.combo.ComboConstants;
import org.ejc.tech.combo.ComboMgr;

import com.sun.org.apache.bcel.internal.generic.NEWARRAY;

/**
 * @struts.action path="/struts/register/registrationAction" scope="request"
 *                parameter="methodToCall" name="registrationForm"
 *                validate="false"
 *                input="/struts/register/createRegistrant.jsp"
 * 
 * @struts.action-forward name="preCreateSuccess" path="/struts/register/createRegistrant.jsp"
 * @struts.action-forward name="createSuccess" path="/struts/register/paymentAction.do?methodToCall=prePayment"
 * 
 * 
 * @author zac, Brian Boyle
 *
 */
public class RegistrationAction extends DispatchAction implements ComboConstants{
	
	private static Logger log = Logger.getLogger(RegistrationAction.class); 
	
	/**
	 * PreCreate Action.<p/>
	 * This is called when the user clicks on "create new registrant" <p/>
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public final ActionForward preCreate(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		if(log.isDebugEnabled()){
			log.debug("In Precreate of Registration Action!");
		}
		
		RegistrationForm regForm=new RegistrationForm();
		AddressForm addressForm=new AddressForm();
		regForm.setAddressForm(addressForm);
		//Set the default registrant type as Guest
		regForm.setRegistrantTypeId(1);
		request.setAttribute("registrationForm",regForm);

		//Setup the dropdown lists
		request.setAttribute("countries",getCountryListing(request.getLocale()));
		request.setAttribute("registrantTypes",getRegistrantTypesListing(request.getLocale()));
		request.setAttribute("accomodationTypes",getAccomodationTypesListing(request.getLocale()));
		
		
		
		//Set the current Action
		HttpSession session = request.getSession();
		//This is to try and set the timeout to a longer time
		session.setMaxInactiveInterval(5000);
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		ejcSession.setCurrentAction("Register Guest");
		
		boolean isConvActive=RegistrationAPIUtil.getLocalHome().create().isConventionActive();
		if(isConvActive){
			ejcSession.getConvention().setConventionStatus("ACTIVE");
		}else{
			ejcSession.getConvention().setConventionStatus("INACTIVE");
		}
		
		
		//Reset all the values from the previouse registration
		ejcSession.setCurrentPrice(null);
		ejcSession.setTransaction(null);
		ejcSession.setConventionRegistrant(null);
		return mapping.findForward("preCreateSuccess");
	}
	
	/**
	 * Validate the registrant input and then create the registrant
	 * @param mapping 
	 * @param form The Registration Form
	 * @param request The request
	 * @param response The response
	 * @return Forward user to payment page
	 * @throws Exception
	 */
	public final ActionForward createRegistrant(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		//manually call validate here.
		//This is better as we can stuff any lists back into the request at this level.
		//If we left it up to struts automatic validation we would loose any such lists , eg
		//List of countries, list of registrants etc...(ZB)
		log.fatal("Calling validate now .............................................");
		
		boolean isConvActive=RegistrationAPIUtil.getLocalHome().create().isConventionActive();
		
		ActionMessages errors = form.validate( mapping, request );
		
		if(!isConvActive){
			if(errors==null)errors=new ActionMessages();
			errors.add("InactiveConv",new ActionMessage("convention.inactive"));
		}
		
		if ( (errors != null && !errors.isEmpty())  || isConvActive==false) {
			log.fatal("There are errors");
			saveErrors(request, errors);            
			//Setup the dropdown lists again
			request.setAttribute("countries",getCountryListing(request.getLocale()));
			request.setAttribute("registrantTypes",getRegistrantTypesListing(request.getLocale()));
			request.setAttribute("accomodationTypes",getAccomodationTypesListing(request.getLocale()));
			return (mapping.findForward("preCreateSuccess"));
		}
		
		RegistrationForm aregForm = (RegistrationForm)form;
		//Create the registrant
		ConventionRegistrant conventionReg = createDetails(aregForm, request);
		
//		try{
//			EmailAPIUtil.getLocalHome().create().sendEmailToRegistrant(conventionReg.getRegistrantId());
//		}catch(Exception e){
//			log.fatal("Error in sending mail");
//		}
//		
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		ejcSession.setConventionRegistrant(conventionReg);
		request.setAttribute("registrationForm",aregForm);
		
		return mapping.findForward("createSuccess");
	}
	
	/**
	 * Retrieve a list of the countries
	 * @param locale The user locale
	 * @return List of countries
	 */
	private Collection getCountryListing(Locale locale){
		return ComboMgr.getInstance().getComboContents(COUNTRY,locale);
	}
	
	/**
	 * Retrieve a list of the RegistrantTypes
	 * @param locale The user locale
	 * @return List of RegistrantTypes
	 */
	private Collection getRegistrantTypesListing(Locale locale){
		return ComboMgr.getInstance().getComboContents(REGISTRANT_TYPE,locale);
	}
	
	/**
	 * Retrieve a list of the AccomodationTypes
	 * @param locale The user locale
	 * @return List of AccomodationTypes
	 */
	private Collection getAccomodationTypesListing(Locale locale){
		return ComboMgr.getInstance().getComboContents(ACCOMODATION_TYPE,locale);
	}
	
	/**
	 * Populate all the Registrant and ConventionRegistrant objects and call the
	 * createFullRegistrant bean method to insert the details to the DB.
	 * @param form The registrantion form
	 * @param request The request
	 */
	private ConventionRegistrant createDetails(RegistrationForm form, HttpServletRequest request)
	{
		ConventionRegistrant conventionReg = new ConventionRegistrant();;
		try{
			/*REGISTRANT*/
			//Create the core registrant details
			Registrant registrant=new Registrant();
			registrant.setEmail(form.getEmail());
			registrant.setFirstName(form.getFirstName());
			registrant.setLastName(form.getLastName());
			registrant.setNotes(form.getNotes());
			registrant.setContactNumber(form.getContactNumber());
			
			//Create the Address details
			Address persistAddress=new Address();
			persistAddress.setAddressLine1(form.getAddressLine1());
			persistAddress.setAddressLine2(form.getAddressLine2());
			persistAddress.setCityTown(form.getCityTown());
			
			//Create the countryCode and set it in the address
			CountryCode countryCode = new CountryCode();
			countryCode.setCountryId(form.getCountryCodeCountryId());
			persistAddress.setCountryCode(countryCode);
			
			//Set the address in the Registrant object
			registrant.setAddress(persistAddress);
			
			registrant.setAgeBracket(form.getAgeBracket());
			
			
			/*CONVENTION REGISTRANT*/
			//Create the accomodationType
			AccomodationType accomType = new AccomodationType();
			if(form.getAccomodationTypeId() == 0){
				accomType.setAccomodationTypeId(5);
			}
			else{
				accomType.setAccomodationTypeId(form.getAccomodationTypeId());
			}
			
			
			//Create the RegistrantType
			RegistrantType regType = new RegistrantType();
			regType.setRegistrantTypeId(form.getRegistrantTypeId());
			
			//Get the ejcSession object from the session so that we can get the convention
			HttpSession session = request.getSession();
			EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
			
			//Set all the values in the conventionRegistrant object
			conventionReg.setAccomodationType(accomType);
			conventionReg.setLengthOfStay(form.getLengthOfStay());
			conventionReg.setRegistrantType(regType);
			conventionReg.setConvention(ejcSession.getConvention());
			conventionReg.setRegistrant(registrant);
			
			if(form.getPreRegistration()){
				conventionReg.setPreReg("true");
			}else{
				conventionReg.setPreReg("false");
			}
			//Create the registrant with the registrant and conventionRegistrant objects
			conventionReg = RegistrationAPIUtil.getLocalHome().create().createFullRegistrant(registrant,  conventionReg);
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return conventionReg;
	}
	
	
}
